/*
 * Copyright 2007-2008 by Matthias Buch-Kromann <mbk.isv@cbs.dk>.
 * 
 * This file is part of the Open-source Dependency Toolkit (OSDT),
 * see http://code.google.com/p/open-source-dependency-toolkit. 
 * 
 * The OSDT is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * The OSDT is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the OSDT in the file COPYING and COPYING.LESSER. If not, see
 * http://www.gnu.org/licenses.
 */

package org.osdtsystem.graphs;

import org.osdtsystem.exceptions.FeatureNotFoundException;
import org.osdtsystem.exceptions.LayerNotFoundException;
import org.osdtsystem.exceptions.NodeNotFoundException;
import org.osdtsystem.exceptions.LocationNotFoundException;
import org.osdtsystem.values.NodeID;
import org.osdtsystem.values.Location;
import org.osdtsystem.values.Layer;
import org.osdtsystem.values.Feature;
import org.osdtsystem.values.EdgeID;
import org.osdtsystem.exceptions.NonUniqueNameException;
import org.osdtsystem.graphs.views.View;
import org.osdtsystem.graphs.views.ViewID;

/**
 * The public graph interface for all methods that are used to alter the graph.
 * @author Matthias Buch-Kromann <mbk.isv@cbs.dk>
 */
public interface GraphConstructionInterface {
    // Layers
    /**
     * Adds a named layer to the graph. 
     * @param name the name of the layer  
     * @return the Layer ID for the layer
     */
    public Layer addLayer(String name);

    /**
     * Deletes a named node layer from the graph. This command only deletes the
     * association between a node layer name and its integer ID, it doesn't 
     * delete all nodes in the layer. 
     * @param layer the integer ID for the node layer
     */
    public void removeLayer(Layer layer);

    // Views
    /**
     * Add a new view with the given unique name to the graph.
     * @param view the view
     * @param name the unique name
     * @return the view id
     * @throws NonUniqueNameException 
     */
    public ViewID addView(View view, String name) throws NonUniqueNameException;
    

    // Nodes
    /**
     * Creates a new node and adds it to the graph. After the node has been 
     * created, it is immodifiable. 
     * @param layer the layer containing the node
     * @return the created node
     * @throws LayerNotFoundException the specified layer does not exist
     */
    public NodeID addNode(Layer layer)
            throws LayerNotFoundException;

    /**
     * Creates a new named node and adds it to the graph. After the node has been
     * created, it is immodifiable.
     * @param layer the layer containing the node
     * @param name the name of the node
     * @return the created node
     * @throws LayerNotFoundException the specified layer does not exist
     */
    public NodeID addNode(Layer layer, String name)
            throws LayerNotFoundException;

    /**
     * Deletes a node from the graph and returns <code>true</code> if the
     * deletion is successful, ie, the node is absent from the graph afterwards.
     * @param node the node that must be deleted
     */
    public void removeNode(NodeID node);

    /**
     * Sets a name for a given node. A name can only refer to one node, but a
     * node may have several different names. 
     * @param node the node that is named
     * @param name the unique name
     * @throws NodeNotFoundException 
     */
    public void setNodeName(NodeID node, String name)
            throws NodeNotFoundException;

    // Edges
    /**
     * Adds an edge to the graph. Edges are uniquely specified by their edge type
     * and their (ordered) sets of in- and out-nodes. 
     * @param in the node where the edge ends
     * @param out the node where the edge starts
     * @param layer the layer containing the edge
     * @return the created edge
     * @throws NodeNotFoundException
     * @throws LayerNotFoundException 
     */
    public EdgeID addEdge(NodeID in, NodeID out, Layer layer)
            throws NodeNotFoundException, LayerNotFoundException;

    /**
     * Deletes an edge from the graph and returns <code>true</code> if the
     * deletion is successful, ie, the node is absent from the graph afterwards.
     * @param edge the edge that must be deleted
     */
    public void removeEdge(EdgeID edge);

    // Features
    /**
     * Register the given feature as valid in the given layer.
     * @param layer the given layer
     * @param feature the feature that must be added to the layer
     * @throws LayerNotFoundException 
     */
    void addLayerFeature(final Layer layer, final Feature feature)
            throws LayerNotFoundException;

    /**
     * Deletes a given local feature. 
     * @param loc the location
     * @param feat the feature
     */
    public void removeFeature(Location loc, Feature feat);

    /**
     * Sets a local feature to a given value, where the feature is specified 
     * by means of a feature ID.
     * @param loc the location
     * @param feat the feature
     * @param val the value
     * @throws LocationNotFoundException
     * @throws FeatureNotFoundException 
     */
    public void setFeatureValue(Location loc, Feature feat, Object val)
            throws LocationNotFoundException, FeatureNotFoundException;

    public int revision();
    
    /**
     * Delete all layers, nodes, edges, etc. in the graph (does not affect
     * base graph).
     */
    public void clear();

    public void clear(Layer layer);

}
